package notice

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"sync"
	"time"
)

type WeiXinNoticer struct {
	config   *WeiXinConfig
	mergeMap map[string]*weixinMessage
	m        sync.Mutex
}

type weixinMessage struct {
	num     string
	content string
}

func (this *WeiXinNoticer) Send(num string, content string) (string, error) {
	payload := this.newPayload(num, content)
	urladdr := fmt.Sprintf("%s?%s", this.config.Addr, payload.Encode())
	resp, err := http.Get(urladdr)

	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(body), nil
}

func (this *WeiXinNoticer) SendMerge(key string, num string, content string) {
	if this.mergeMap == nil {
		this.mergeMap = make(map[string]*weixinMessage)
	}
	msg := &weixinMessage{
		num:     num,
		content: content,
	}
	this.m.Lock()
	this.mergeMap[key] = msg
	this.m.Unlock()
}

func (this *WeiXinNoticer) newPayload(id string, content string) url.Values {
	v := url.Values{}
	v.Add("user", this.config.User)
	v.Add("key", this.config.Password)
	v.Add("user_id", id)
	v.Add("message", content)
	return v
}

func NewWeiXinNoticer(config *WeiXinConfig) *WeiXinNoticer {
	wxn := WeiXinNoticer{}
	if config == nil {
		wxn.config = NewWeiXinConfig()
	} else {
		wxn.config = config
	}
	if config.Interval > 0 {
		go func() {
			ticker := time.NewTicker(time.Duration(config.Interval) * time.Second)
			for {
				select {
				case <-ticker.C:
					wxn.m.Lock()
					for key, msg := range wxn.mergeMap {
						ret, err := wxn.Send(msg.num, msg.content)
						log.Printf("weixin send %s, content: %s, ret: %s, err: %v", msg.num, msg.content, ret, err)
						delete(wxn.mergeMap, key)
					}
					wxn.m.Unlock()
				}
			}
		}()
	}
	return &wxn
}
